/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package e.odbo.data.impexp;

import com.openbravo.data.loader.sentence.SentenceExec;
import e.odbo.data.dao.table.I_TableSentenceBuilder;
import e.odbo.data.dao.table.TableDefinition;
import e.odbo.data.impexp.engine.csv.CSVEngine;
import e.odbo.data.impexp.model.AbstractImpExpTableDefinition;
import e.odbo.data.impexp.model.ImpExpRowDefinition;
import e.odbo.data.impexp.model.ImpExpTableDefinition;
import e.odbo.data.impexp.processor.ExportObjectConverProcessor;
import e.odbo.data.impexp.processor.ImportObjectConverProcessor;
import e.odbo.data.impexp.processor.ImportObjectStateProcessor;
import com.openbravo.data.basic.BasicException;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Administrator
 */
public class ImpExpManager {

    static Map<String, List<TableDefinition>> defaultTableGroups = new HashMap<String, List<TableDefinition>>();
    static TableDefinitionTreeNode tableTreeRoot = new TableDefinitionTreeNode();
    static Map<String, List<ImpExpTableTrigger>> tableTriggers = new HashMap<String, List<ImpExpTableTrigger>>();
    private static Map<String, Class> enginesMap = new HashMap();//执行器注册类表
    ImpExpConfig config;
    List<AbstractImpExpTableDefinition> impExpTableDefinition = new ArrayList<AbstractImpExpTableDefinition>();

    ImportObjectConverProcessor defaultImportProcessor = new ImportObjectConverProcessor(this);
    ExportObjectConverProcessor defaultExportProcessor = new ExportObjectConverProcessor(this);
    ImportObjectStateProcessor defaultImportStateProcessor = new ImportObjectStateProcessor(this);

    private static Map<String, FieldConverse> fieldConverses = new HashMap();
    private static Map<String, FieldGenerator> fieldGenerator = new HashMap();


    public static final ImpExpManager INSTANCE = new ImpExpManager();

    I_TableSentenceBuilder tableSentenceBuilder;

    public static void regist(String engineName, Class engineClass) {
        enginesMap.put(engineName, engineClass);
    }

    public ImpExpManager() {
        enginesMap.put(CSVEngine.PROPERTY_prefix, CSVEngine.class);
    }


    public void init(ImpExpConfig config, I_TableSentenceBuilder tableSentenceBuilder) {
        if (config == null) {
            config = new ImpExpConfig();
        }
        this.config = config;
        this.tableSentenceBuilder = tableSentenceBuilder;
        buildImpExpTableDefinitions(tableTreeRoot);
    }


    private void buildImpExpTableDefinitions(TableDefinitionTreeNode node) {
        for (TableDefinitionTreeNode cNode : node.getNodes()) {
            buildImpExpTableDefinitions(cNode);
        }
        for (TableDefinition table : node.getTables()) {
            impExpTableDefinition.add(new ImpExpTableDefinition(table, tableSentenceBuilder));
        }
    }

    public void doImport(String type) throws BasicException {
        ImpExpEngine engine;
        try {
            engine = (ImpExpEngine) enginesMap.get(type).newInstance();
        } catch (InstantiationException e) {
            throw new BasicException(e);
        } catch (IllegalAccessException e) {
            throw new BasicException(e);
        }
        engine.init(this);
        for (AbstractImpExpTableDefinition impExpTable : impExpTableDefinition) {
            engine.importTable(impExpTable, null);
            doImportToDb(impExpTable);
        }
    }

    public void doImportToDb(AbstractImpExpTableDefinition impExpTable) throws BasicException {
        defaultImportProcessor.process(impExpTable);
        defaultImportStateProcessor.process(impExpTable);
        SentenceExec insertSent = impExpTable.getInsertSentence();
        SentenceExec updateSent = impExpTable.getUpdateSentence();
        int rowCount = impExpTable.getRowCount();
        for (int i = 0; i < rowCount; i++) {
            ImpExpRowDefinition row = impExpTable.getRow(i);
            if (ImpExpRowDefinition.STATE_Import_Insert == row.getState())
                insertSent.exec(row.getDatas());
            else if (ImpExpRowDefinition.STATE_Import_Update == row.getState())
                updateSent.exec(row.getDatas());
        }
    }

    public void doExport(String type, Date start, Date end) throws BasicException {
        ImpExpEngine engine;
        try {
            engine = (ImpExpEngine) enginesMap.get(type).newInstance();
        } catch (InstantiationException e) {
            throw new BasicException(e);
        } catch (IllegalAccessException e) {
            throw new BasicException(e);
        }
        engine.init(this);
        for (AbstractImpExpTableDefinition impExpTable : impExpTableDefinition) {
            loadDBStoreDate(impExpTable, start, end);
            defaultExportProcessor.process(impExpTable);
            engine.exportTable(impExpTable, null);
        }
    }

    public void doExport(AbstractImpExpTableDefinition impExpTable, String type, String fileName) throws BasicException {
        ImpExpEngine engine;
        try {
            engine = (ImpExpEngine) enginesMap.get(type).newInstance();
        } catch (InstantiationException e) {
            throw new BasicException(e);
        } catch (IllegalAccessException e) {
            throw new BasicException(e);
        }
        engine.init(this);
        defaultExportProcessor.process(impExpTable);
        engine.exportTable(impExpTable, fileName);
    }


    public void loadDBStoreDate(AbstractImpExpTableDefinition table, Date start, Date end) throws BasicException {

        //String sql = table.getListSQL(start, end);
        //List data = new StaticSentence(table.getSession(), sql, null, table.getSerializerReadBasic()).list();
        List data = table.getListWithTimeSentence(table.getSerializerReadBasic(), start, end).list();
        for (Object o : data) {
            table.addRow(new ImpExpRowDefinition((Object[]) o));
        }
    }

    public List<AbstractImpExpTableDefinition> getImpExpTableDefinition() {
        return impExpTableDefinition;
    }

    public void setImpExpTableDefinition(
            List<AbstractImpExpTableDefinition> impExpTableDefinition) {
        this.impExpTableDefinition = impExpTableDefinition;
    }

    public FieldConverse getTableFieldConverse(String table, String field) {
        String fieldConverseName = config.getTableFieldConverse(table, field);
        return null;
    }

    public FieldGenerator getTableFieldGenerator(String table, String field) {
        String fieldGeneratorName = config.getTableFieldConverse(table, field);
        return null;
    }

    public ImpExpManager regeditTable(TableDefinition table) {
        impExpTableDefinition.add(new ImpExpTableDefinition(table, tableSentenceBuilder));
        return this;
    }


    public ImpExpManager regeditTables(List<TableDefinition> tables) {
        for (TableDefinition t : tables)
            impExpTableDefinition.add(new ImpExpTableDefinition(t, tableSentenceBuilder));
        return this;
    }

    public String getDirStory() {
        return "c:/pos_back/";
    }

    public void exportTableDate(AbstractImpExpTableDefinition impExpTable, String type) throws BasicException {
        ImpExpEngine engine;
        try {
            engine = (ImpExpEngine) enginesMap.get(type).newInstance();
        } catch (InstantiationException e) {
            throw new BasicException(e);
        } catch (IllegalAccessException e) {
            throw new BasicException(e);
        }
        engine.init(this);
        engine.exportTable(impExpTable, null);
    }


    public void importTableDate(AbstractImpExpTableDefinition impExpTable, String type, String fileName) throws BasicException {
        ImpExpEngine engine;
        try {
            engine = (ImpExpEngine) enginesMap.get(type).newInstance();
        } catch (InstantiationException e) {
            throw new BasicException(e);
        } catch (IllegalAccessException e) {
            throw new BasicException(e);
        }
        engine.init(this);
        engine.importTable(impExpTable, fileName);
    }
}
